﻿using System;
using System.Drawing;
using System.IO;
using System.Media;
using System.Threading;
using System.Windows.Forms;
using CC.Utilities.Drawing;
using CC.Yacht.Interfaces;
using CC.Yacht.Utilities;

namespace CC.Yacht.Windows.Forms
{
    public class DieControl : UserControl, IDie
    {
        #region Constructor
        public DieControl()
        {
            InitializeComponent();

            _Die.Changed += _Die_Changed;
        }

        public DieControl(DieFace face) : this()
        {
            _Die.Face = face;
        }

        ~DieControl()
        {
            Dispose();
        }
        #endregion

        #region Private Fields
        private Color _BorderColor = Color.Black;
        private bool _CanLock = true;
        private readonly Die _Die = new Die(DieFace.None);
        private Color _DieColor = Color.White;
        private Color _LockedBorderColor = Color.Gold;
        private Color _LockedDieColor = Color.White;
        private Color _LockedForeColor = Color.Black;
        private readonly IDiePainter _Painter = new GDIDiePainter();
        private int _ScaleMode;
        private SoundPlayer _SoundPlayer;
        #endregion

        #region Public Events
        public event EventHandler<DieChangedEventArgs> Changed;
        #endregion

        #region Public Properties
        public Color BorderColor
        {
            get { return _BorderColor; }
            set { _BorderColor = value; Refresh(); }
        }

        public bool CanLock
        {
            get { return _CanLock; }
            set { _CanLock = value;}
        }

        public Color DieColor
        {
            get { return _DieColor; }
            set { _DieColor = value; Refresh(); }
        }

        public DieFace Face
        {
            get { return _Die.Face; }
            set { _Die.Face = value; Refresh(); }
        }

        public bool Locked
        {
            get { return _Die.Locked; }
            set { _Die.Locked = value; }
        }

        public Color LockedBorderColor
        {
            get { return _LockedBorderColor; }
            set { _LockedBorderColor = value; Refresh(); }
        }

        public Color LockedDieColor
        {
            get { return _LockedDieColor; }
            set { _LockedDieColor = value; Refresh(); }
        }
        
        public Color LockedForeColor
        {
            get { return _LockedForeColor; }
            set { _LockedForeColor = value; Refresh(); }
        }
        
        public int ScaleMode
        {
            get { return _ScaleMode; }
            set { _ScaleMode = value; Refresh(); }
        }
        #endregion

        #region Private Methods
        // ReSharper disable InconsistentNaming
        private void _Die_Changed(object sender, DieChangedEventArgs e)
        // ReSharper restore InconsistentNaming
        {
            Refresh();
            Application.DoEvents();
            Thread.Sleep(5);
            OnChanged(e);
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // DieControl
            // 
            this.DoubleBuffered = true;
            this.Name = "DieControl";
            this.Size = new System.Drawing.Size(32, 32);
            this.ResumeLayout(false);

        }

        private void PlaySound(Stream stream)
        {
            if (_SoundPlayer == null)
            {
                _SoundPlayer = new SoundPlayer(this);
            }

            _SoundPlayer.Play(stream);
        }
        #endregion

        #region Protected Methods
        private void OnChanged(DieChangedEventArgs eventArgs)
        {
            if (Changed != null)
            {
                Changed(this, eventArgs);
            }
        }

        protected override void OnClick(EventArgs e)
        {
            if (_CanLock)
            {
                if (_Die.Face != DieFace.None)
                {
                    _Die.Locked = !_Die.Locked;

                    PlaySound(Yacht.Properties.Resources.Click);
                }
                else
                {
                    SystemSounds.Beep.Play();
                }
            }

            base.OnClick(e);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            _Painter.Draw(e.Graphics, _Die, ClientRectangle, _ScaleMode, _BorderColor, _DieColor, ForeColor, _LockedBorderColor, _LockedDieColor, _LockedForeColor);
        }
        #endregion

        #region Public Methods
        public static implicit operator Die(DieControl dieControl)
        {
            return new Die(dieControl.Face, dieControl.Locked);
        }

        public new void Dispose()
        {
            if (InvokeRequired)
            {
                BeginInvoke(new MethodInvoker(Dispose));
            }
            else
            {
                if (_SoundPlayer != null)
                {
                    _SoundPlayer.Dispose();
                    _SoundPlayer = null;
                }

                base.Dispose();
            }
        }

        public void Reset()
        {
            _Die.Reset();    
            //Refresh();
        }

        public void Roll()
        {
            _Die.Roll();
        }
        #endregion
    }
}
